package com.corticon.dialogs.web.designer;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.annotation.PostConstruct;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.rpc.ServiceException;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import com.corticon.dialogs.dao.DataTypeDAO;
import com.corticon.dialogs.dao.FunctionDAO;
import com.corticon.dialogs.dao.LocaleDAO;
import com.corticon.dialogs.dao.ProductTypeDAO;
import com.corticon.dialogs.dao.PublicationStatusTypeDAO;
import com.corticon.dialogs.dao.QuestionSetDAO;
import com.corticon.dialogs.dao.QuestionSetInNaireDAO;
import com.corticon.dialogs.dao.QuestionnaireDAO;
import com.corticon.dialogs.dao.RegionDAO;
import com.corticon.dialogs.dao.ResponseTypeDAO;
import com.corticon.dialogs.dao.ThemeDAO;
import com.corticon.dialogs.dao.UiControlDAO;
import com.corticon.dialogs.dao.UserDAO;
import com.corticon.dialogs.dao.UserGroupDAO;
import com.corticon.dialogs.dao.hibernate.QuestionManager;
import com.corticon.dialogs.dao.hibernate.QuestionnaireManager;
import com.corticon.dialogs.dto.PreviewQuestionDTO;
import com.corticon.dialogs.dto.QuestionSetDTO;
import com.corticon.dialogs.model.support.PublicationStatus;
import com.corticon.dialogs.model.DataType;
import com.corticon.dialogs.model.Function;
import com.corticon.dialogs.model.Locale;
import com.corticon.dialogs.model.PermissionType;
import com.corticon.dialogs.model.ProductType;
import com.corticon.dialogs.model.PublicationStatusType;
import com.corticon.dialogs.model.QuestionSet;
import com.corticon.dialogs.model.QuestionSetInNaire;
import com.corticon.dialogs.model.Questionnaire;
import com.corticon.dialogs.model.Region;
import com.corticon.dialogs.model.Theme;
import com.corticon.dialogs.model.User;
import com.corticon.dialogs.model.UserGroup;
import com.corticon.dialogs.service.QuestionSetService;
import com.corticon.dialogs.service.QuestionnaireService;
import com.corticon.dialogs.util.CommonSupport;
import com.corticon.dialogs.util.GenericFunction;
import com.corticon.dialogs.util.Pager;
import com.corticon.dialogs.util.QuestionUtils;
import com.corticon.dialogs.util.security.CustomUserDetails;
import com.corticon.dialogs.util.security.SecurityUtils;
import com.corticon.dialogs.util.webservice.CcServerMessagingAxis;
import com.corticon.dialogs.util.webservice.CcServerMessagingAxisService;
import com.corticon.dialogs.util.webservice.CcServerMessagingAxisServiceLocator;
import com.corticon.dialogs.validation.designer.QuestionnaireValidator;
import com.corticon.dialogs.web.BaseController;
import com.corticon.dialogs.web.DialogsRequestURL;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.text.SimpleDateFormat;

import org.springframework.web.util.HtmlUtils;

/**
 * dialog controller
 * 
 * @author heweiya
 */
@Controller
@SessionAttributes( { "dialog", "questionnaire", "functions", "locales", "regions", "productTypes", "themes", "serviceNames" })
public class QuestionnaireController extends BaseController {

	private static final Log logger = LogFactory.getLog(QuestionnaireController.class);
	private final String[] MessageKeys = { "error" };
	private final String MESSAGE_KEY = "error";
	// RequestURIs
	// TODO: modify gen link url.
	private final String NEW_VERSION_REQUEST = "newversion";
	private final String CHECK_DIALOG_STATUE = "checkdialog";
	private final String LINK_PAGES_REQUEST = "pages";
	private final String EDIT_PAGES_REQUEST = "editpage";
	private final String DEL_REQUEST = "delete";
	private final String SEARCH_PAGE_REQUEST = "searchpage";
	private final String CHECK_PAGE_REQUEST = "checkpage";
	private final String REPLICATE_REQUEST = "replicate";
	private final String COPY_REQUEST = "copy";
	private final String PUBLISH_REQUEST = "publish";
	private final String RETIRE_RESUEST = "retire";
	private final String CHECK_DIALOG_PUBLISH = "checkpublish";
	private final String SEARCH_KEYWORD = "dialogSearchKey";
	private final String EXPORT_XMI_REQUEST = "exportxmi";
	// message
	private String createDialogFirstMessage = "question.create.firstmsg";
	private String publicCancelMessage = "general.action.cancel";
	private String questionnaireFoundMessage = "dialog.found";
	private String dialogCreateSuccessMessage = "dialog.create.success";
	private String emptyDialogMessage = "dialog.empty";
	private String dialogUpdateSuccessMessage = "dialog.update.success";
	private String publishedMessage = "dialog.published";
	private String retiredMessage = "dialog.retired";
	private String deletedMessage = "dialog.delete.success";
	private String havePageMessage = "dialog.havepage";
	private String dialogRetireConfirmMessage = "dialog.retire.confirm";
	private String dialogRetireNoteMessage = "dialog.retirenote.empty";
	private String dialogRetireSuccessMessage = "dialog.retire.success";
	private String dialogRetireNoteLenMessage = "questionBase.retirednote.length";
	private String dialogPublishNoteMessage = "dialog.publishnote.empty";
	private String dialogPublishEffectiveMessage = "dialog.publisheffective.empty";
	private String dialogPublishSuccessMessage = "dialog.publish.success";
	private String dialogPublishIncorrectMessage = "dialog.publish.incorrectdate";
	private String dialogPublishLenMessage = "dialog.publishtext.length";
	private String dialogPublishNoServiceMessage = "dialog.publish.noservice";
	private String dialogPublishLockedMessage = "dialog.publish.locked";
	private String Msg_effectiveDate = "Msg_effectiveDate";
	private String Msg_publishText = "Msg_publishText";
	private String Msg_incorrectDate = "Msg_incorrectDate";
	private String Msg_publishTextLen = "Msg_publishTextLen";
	private String Msg_noServiceName = "Msg_noServiceName";
	private String dialogIncludeHaveMessage = "dialog.includepage.haveit";
	private String dialogIncludeRetireMessage = "dialog.includepage.retire";
	private String dialogIncludeSuccessMessage = "dialog.includepage.success";
	private String dialogIncludeSelectMesssage = "dislog.includepage.selectone";
	private String dialogIncludePageMessage = "dialog.includepage.pages";

	// DAOs
	@Resource
	private UserDAO userDAO;
	@Resource
	QuestionnaireDAO questionailDAO;
	@Resource
	QuestionSetDAO questionSetDAO;
	@Resource
	private UserGroupDAO userGroupDAO;
	@Resource
	private PublicationStatusTypeDAO publicationStatusTypeDAO;
	@Resource
	private QuestionnaireManager questionnaireManager;
	@Resource
	private FunctionDAO functionDAO;
	@Resource
	private LocaleDAO localeDAO;
	@Resource
	private RegionDAO regionDAO;
	@Resource
	private ProductTypeDAO productTypeDAO;
	@Resource
	private ThemeDAO themeDAO;
	@Resource
	private QuestionnaireDAO questionnaireDAO;
	@Resource
	private QuestionSetInNaireDAO questionSetInNaireDAO;
	@Resource
	private QuestionManager questionManager;
	@Resource
	private UiControlDAO uiControlDAO;	
	@Resource
	private DataTypeDAO dataTypeDAO;

	// Services.
	@Resource
	private QuestionnaireService questionnaireService;
	@Resource
	private QuestionSetService questionSetService;

	// Other Resources.
	@Resource
	private CommonSupport commonSupport;

	// Validators.
	private QuestionnaireValidator questionnaireValidator;
	private Configuration cfg = new Configuration();

	@PostConstruct
	public void buildValidators() {
		questionnaireValidator = new QuestionnaireValidator(validationMessageFormatter);
	}

	@RequestMapping(value = LIST_REQUEST, method = RequestMethod.GET)
	public String list(@RequestParam(required = false)
	Integer page, ModelMap model, HttpServletRequest request) {
		// loginuser && security
		// Get the permission list for the current user.
		List<String> permissions = SecurityUtils.getCurrentUserPermissions();
		// Get the current user.
		CustomUserDetails currentUserDetails = SecurityUtils.getCurrentUser();
		User currentUser = userDAO.findById(currentUserDetails.getUsername());
		// page
		Pager pager = constructPager(page, request);
		// Pager pager = new Pager();
		pager = setPagerSort(pager, "questionnaireId", request);
		request.setAttribute("pager", pager);
		request.setAttribute("order", request.getParameter("sortBy"));
		request.setAttribute("column", request.getParameter("sortColumn"));

		request.setAttribute(PAGER_NAME, pager);
		String checkSearch = "";
		if (request.getParameterValues("checkSearch") != null) {
			if (request.getSession().getAttribute(SEARCH_KEYWORD) != null) {
				String searchPara = (String) request.getSession().getAttribute(SEARCH_KEYWORD);
				return redirectPrefix + DialogsRequestURL.SEARCH + requestSuffix + "?" + searchPara;
			}
		}
		// if (request.getSession().getAttribute(SEARCH_KEYWORD) != null) {
		// String searchPara = (String)
		// request.getSession().getAttribute(SEARCH_KEYWORD);
		// return redirectPrefix + DialogsRequestURL.SEARCH + requestSuffix +
		// "?" + searchPara;
		// }
		// list
		List<Questionnaire> dialogs = new ArrayList<Questionnaire>();
		// Create a questionnaire example.
		Questionnaire qsExample = new Questionnaire();

		// If the current user is sys admin, he can view all of the question
		// sets.
		if (permissions.contains(PermissionType.SYS_ADMIN.value())) {
			pager.setNumOfRecords(questionnaireDAO.getCountAll());
			dialogs = questionnaireDAO.getPageOfDataAll(pager);
		} else if (permissions.contains(PermissionType.PORTAL_USER.value())) {
			// If the current user is portal user, he can only view the question
			// sets belong to him.
			qsExample.setModifiedBy(currentUser);
			pager.setNumOfRecords(questionnaireDAO.getCountByExample(qsExample, "version"));
			dialogs = questionnaireDAO.getPageOfDataByExample(qsExample, pager, "version");
		} else {
			// If the current user is in other roles, he can only view the
			// question sets belong to
			// his group.
			UserGroup group = userGroupDAO.load(currentUserDetails.getGroupName());
			dialogs = questionnaireDAO.getPageOfDataByGroup(group, pager);
			pager.setNumOfRecords(questionnaireDAO.getCountByGroup(group));
		}
		// output
		loadUsersAndGroupsInfoByPermission(currentUserDetails, request);
		generalGet(model, false, currentUser);
		readMessages(defaultMessageKeys, request);

		if (dialogs != null && dialogs.size() > 0) {
			model.addAttribute("dialogs", dialogs);
			request.setAttribute("error", getMessage(String.valueOf(pager.getNumOfRecords()), questionnaireFoundMessage));
		} else {
			request.setAttribute("error", getMessage("", publicNotFoundMessage));
		}
		String from = "";
		if (request.getParameterValues("from") != null) {
			from = request.getParameterValues("from")[0];
			request.setAttribute("message", getMessage("", publicCancelMessage));
		}
		model.addAttribute("from", from);

		return "designer.questionnaire.list";
	}

	/**
	 * The method is used to render the page before display the create dialog
	 * page. If you want to put a model into requestScope, use method
	 * addAttribute in {@link ModelMap}.
	 * 
	 * @param model
	 * @return
	 */
	@Transactional(readOnly = true)
	@RequestMapping(value = CREATE_REQUEST, method = RequestMethod.GET)
	public String entryCreateQuestion(ModelMap model, HttpServletRequest request) {
		// loginuser
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		User currentUser = userDAO.findById(currentAdmin.getUsername());
		generalGet(model, true, currentUser);
		request.setAttribute("error", getMessage("", createDialogFirstMessage));
		// init
		Questionnaire questionnaire = new Questionnaire();
		// update by last commit 2009.7.1
//		GenericFunction fun = new GenericFunction();
//		questionnaire.setRefId(fun.NextDialogNumber(questionnaireDAO.GetMaxNumber()));
		questionnaire.setVersion(Long.valueOf("1"));
		questionnaire.setModifiedOn(new Date());
		questionnaire.setModifiedBy(userDAO.findById(currentAdmin.getUsername()));
		PublicationStatusType status = publicationStatusTypeDAO.findById("inprocess");
		questionnaire.setPublicationStatus(status);
		questionnaire.setFunction(new Function());
		questionnaire.setLocale(new Locale());
		questionnaire.setProductType(new ProductType());
		questionnaire.setRegion(new Region());
		questionnaire.setTheme(new Theme());
		questionnaire.setSummaryReport(null);
		String Msg_HaveIt = getMessage("", dialogIncludeHaveMessage);
		String Msg_IncludeIt = getMessage("", dialogIncludeSuccessMessage);
		String Msg_Retire = getMessage("", dialogIncludeRetireMessage);
		String Msg_SelectOne = getMessage("", dialogIncludeSelectMesssage);
		request.setAttribute("Msg_HaveIt", Msg_HaveIt);
		request.setAttribute("Msg_IncludeIt", Msg_IncludeIt);
		request.setAttribute("Msg_Retire", Msg_Retire);
		request.setAttribute("Msg_SelectOne", Msg_SelectOne);
		request.setAttribute("questionsSet", "");
		model.addAttribute("dialog", questionnaire);
		model.addAttribute("isCreate", CREATE_FLAG);

		return getViewNameByRequestURI(request);
	}

	/**
	 * Process the form submit of Create dialog Function.
	 * 
	 * @param submitAction
	 *            The type of the action after submit, such as submit, submit
	 *            then new, and so on.
	 * @param newUser
	 *            The html form data bind into this object.
	 * @param errors
	 *            {@link Errors} object, used by the spring validator.
	 * @param sessionStatus
	 *            {@link SessionStatus} used to control the status of the beans
	 *            in session scope.
	 * @return
	 */
	@Transactional()
	@RequestMapping(value = { CREATE_REQUEST, EDIT_REQUEST }, method = RequestMethod.POST)
	public String processCreateQuestion(@RequestParam
	String submitAction, @ModelAttribute("dialog")
	Questionnaire dialog, Errors errors, ModelMap model, HttpServletRequest request, SessionStatus sessionStatus) {
		// login user
		CustomUserDetails currentUser = SecurityUtils.getCurrentUser();
		User user = userDAO.findById(currentUser.getUsername());
		readMessages(defaultMessageKeys, request);

		// Validate the form object.
		String summaryReport = "";
		if (request.getParameterValues("summaryReport") != null) {
			summaryReport = request.getParameterValues("summaryReport")[0];
		}
		if (summaryReport.equals("true")) {
			dialog.setSummaryReport(true);
		}
		if (summaryReport.equals("false")) {
			dialog.setSummaryReport(false);
		}
		String questionsSet = "";
		if (request.getParameterValues("includePage") != null) {
			questionsSet = request.getParameterValues("includePage")[0];
		}
		dialog = escapeQuestionnaire(dialog);
        dialog.setModifiedBy(user);
		questionsSet = questionsSet.replace("questionSet", "");
		String[] set = questionsSet.split(";");
		Map<String, List<String>> errorsMessages = questionnaireValidator.invokeValidate(dialog, errors, request.getLocale());
		request.setAttribute("errors", errorsMessages);
		// dialog = generalGetSelect(dialog, request);
		if (errors.hasErrors()) {
			// add
			String Msg_HaveIt = getMessage("", dialogIncludeHaveMessage);
			String Msg_IncludeIt = getMessage("", dialogIncludeSuccessMessage);
			String Msg_Retire = getMessage("", dialogIncludeRetireMessage);
			String Msg_SelectOne = getMessage("", dialogIncludeSelectMesssage);
			List<QuestionSet> pages = new ArrayList<QuestionSet>();

			for (int i = 0; i < set.length; i++) {
				if (set[i] != null && !set[i].equals("")) {
					QuestionSet questionset = questionSetDAO.findById(Long.valueOf(set[i]));
					pages.add(questionset);
				}
			}
			request.setAttribute("Msg_HaveIt", Msg_HaveIt);
			request.setAttribute("Msg_IncludeIt", Msg_IncludeIt);
			request.setAttribute("Msg_Retire", Msg_Retire);
			request.setAttribute("Msg_SelectOne", Msg_SelectOne);
			request.setAttribute("pagemessage", getMessage(String.valueOf(pages.size()), dialogIncludePageMessage));

			model.addAttribute("isCreate", "isValidate");

			generalGet(model, true, user);
			model.addAttribute("pages", pages);
			model.addAttribute("dialog", dialog);

			return getViewNameByRequestURI(request);
		}
		String locale = "";
		if (!request.getParameterValues("locale.code")[0].equals("")) {
			locale = request.getParameterValues("locale.code")[0];
			dialog.setLocale(questionnaireManager.getLocale(locale));
		} else {
			dialog.setLocale(null);
		}
		//update by last commit 2009.7.1
		if (dialog.getRefId()==null && dialog.getVersion() == 1l){
			GenericFunction fun = new GenericFunction();
			dialog.setRefId(fun.NextDialogNumber(questionnaireDAO.GetMaxNumber()));
		}		
		if (request.getRequestURI().indexOf(CREATE_REQUEST) > -1) {
			addMessages(DEFAULT_MESSAGE_KEY + "=" + dialogCreateSuccessMessage, request, messageSource, null);
			questionnaireDAO.save(dialog);

		}
		if (request.getRequestURI().indexOf(EDIT_REQUEST) > -1) {
			addMessages(DEFAULT_MESSAGE_KEY + "=" + dialogUpdateSuccessMessage, request, messageSource, null);
			questionnaireDAO.update(dialog);
		}

		questionnaireManager.delNarieInSet(dialog);
		for (int i = 0; i < set.length; i++) {
			// insert it
			if (set[i] != null && !set[i].equals("")) {
				QuestionSet questionset = questionSetDAO.findById(Long.valueOf(set[i]));
				questionnaireManager.insertPage(dialog, questionset);
				/**
				 * Second, we need to provide a hook from Questions to
				 * Questionnaire using the epaRefQuestionnaires field. The
				 * reason that we need to do this is to allow Corticon Rules
				 * Studio to grab only the appropriate Question for a given
				 * Questionnaire. The technique for doing this will be to store
				 * the Ref ID and version of the Questionnaire whenever a
				 * Question is included within a Questionnaire on the Include
				 * Dialogs page (AUT04). Now, I realize that we Include Pages
				 * there, so that will require that we update the Question table
				 * for all rows included on the Included Page. I hope this is
				 * making sense. The epaRefQuestionnaires field will contain as
				 * many references as needed, since a Question can be included
				 * in multiple Dialogs. In order to that, we need to concatenate
				 * each reference as a comma delimited string. Here is an
				 * example of what the field may contain:
				 * D-00001V001,D-00001V002,D-00456V010. Conversely, when a
				 * Question gets removed, its reference needs to be removed from
				 * the field.
				 */
				questionnaireManager.responseQuestion(dialog, questionset);
			}

		}

		if (StringUtils.equalsIgnoreCase(submitAction, SUBMIT_AND_NEW)) {
			return redirectPrefix + CREATE_REQUEST + requestSuffix;
		}
		if (StringUtils.equalsIgnoreCase(submitAction, SUBMIT)) {
			return redirectPrefix + VIEW_REQUEST + requestSuffix + "?id=" + dialog.getQuestionnaireId().toString();

		}
		if (StringUtils.equalsIgnoreCase(submitAction, SUBMIT_AND_EXIT)) {
			return redirectPrefix + LIST_REQUEST + requestSuffix + "?checkSearch=list";
		}
		return redirectPrefix + CREATE_REQUEST + requestSuffix;
	}

	@Transactional(readOnly = true)
	@RequestMapping(value = { VIEW_REQUEST, EDIT_REQUEST, LINK_PAGES_REQUEST, EDIT_PAGES_REQUEST, PUBLISH_REQUEST, RETIRE_RESUEST }, method = RequestMethod.GET)
	public String viewQuestion(@RequestParam
	String id, ModelMap model, HttpServletRequest request) {
		// message ??
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		User currentuser = userDAO.findById(currentAdmin.getUsername());
		readMessages(defaultMessageKeys, request);
		readMessages(MessageKeys, request);
		Questionnaire dialog = questionnaireDAO.findById(Long.valueOf(id));

		if (dialog == null) {
			addMessages(DEFAULT_MESSAGE_KEY + "=" + emptyDialogMessage, request, messageSource, null);
			readMessages(defaultMessageKeys, request);
			return errorsViewName;
		}
		model.addAttribute("dialog", dialog);
		List pages = questionnaireManager.getDialogIn(id);
		model.addAttribute("pages", pages);
		request.setAttribute("pagemessage", getMessage(String.valueOf(pages.size()), dialogIncludePageMessage));
		String from = "";
		if (request.getParameterValues("from") != null) {
			from = request.getParameterValues("from")[0];
		}
		request.setAttribute("Msg_Retire_Dialog", getMessage("", retiredMessage));
		request.setAttribute("Msg_Locked", getMessage("", dialogPublishLockedMessage));
		model.addAttribute("from", from);
		if (request.getRequestURI().indexOf(EDIT_REQUEST) > -1) {
			if (dialog.getPublicationStatus() != null && dialog.getPublicationStatus().getCode().equals("published")) {
				return redirectTo403();
			}
			if (dialog.getPublicationStatus() != null && dialog.getPublicationStatus().getCode().equals("retired")) {
				return redirectTo403();
			}
			if (dialog.getLocale() == null) {
				dialog.setLocale(new Locale());
			}
			generalGet(model, true, currentuser);
			String Msg_HaveIt = getMessage("", dialogIncludeHaveMessage);
			String Msg_IncludeIt = getMessage("", dialogIncludeSuccessMessage);
			String Msg_Retire = getMessage("", dialogIncludeRetireMessage);
			String Msg_SelectOne = getMessage("", dialogIncludeSelectMesssage);
			request.setAttribute("error", getMessage("", createDialogFirstMessage));
			request.setAttribute("Msg_HaveIt", Msg_HaveIt);
			request.setAttribute("Msg_IncludeIt", Msg_IncludeIt);
			request.setAttribute("Msg_Retire", Msg_Retire);
			request.setAttribute("Msg_SelectOne", Msg_SelectOne);
			model.addAttribute("isCreate", EDIT_FLAG);
			request.setAttribute("questionsSet", "");
			return getViewNameByRequestURI(request);
		}
		generalPutSelect(dialog, model);
		if (request.getRequestURI().indexOf(PUBLISH_REQUEST) > -1) {
			request.setAttribute("message", getMessage("", createDialogFirstMessage));
			request.setAttribute(Msg_effectiveDate, getMessage("", dialogPublishEffectiveMessage));
			request.setAttribute(Msg_publishText, getMessage("", dialogPublishNoteMessage));
			request.setAttribute(Msg_incorrectDate, getMessage("", dialogPublishIncorrectMessage));
			request.setAttribute(Msg_publishTextLen, getMessage("", dialogPublishLenMessage));
			request.setAttribute(Msg_noServiceName, getMessage("", dialogPublishNoServiceMessage));
		}
		if (request.getRequestURI().indexOf(RETIRE_RESUEST) > -1) {
			readMessages(MessageKeys, request);
			request.setAttribute("message", getMessage("", dialogRetireConfirmMessage));
		}
		return getViewNameByRequestURI(request);
	}

	@Transactional()
	@RequestMapping(value = RETIRE_RESUEST, method = RequestMethod.POST)
	public String retireDialog(@RequestParam
	String submitAction, @ModelAttribute("dialog")
	Questionnaire dialog, Errors errors, ModelMap model, HttpServletRequest request) {
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();

		// If the retired note is empty, return to the form, and display a
		// message.
		readMessages(defaultMessageKeys, request);
		readMessages(MessageKeys, request);
		if (StringUtils.isEmpty(dialog.getRetiredNote())) {
			addMessages(MESSAGE_KEY + "=" + dialogRetireNoteMessage, request, messageSource, null);
			addMessages(DEFAULT_MESSAGE_KEY + "=" + dialogRetireConfirmMessage, request, messageSource, null);
			return redirectPrefix + RETIRE_RESUEST + requestSuffix + "?id=" + dialog.getQuestionnaireId().toString();
		}
		if (dialog.getRetiredNote().length() >= 255) {
			addMessages(MESSAGE_KEY + "=" + dialogRetireNoteLenMessage, request, messageSource, null);
			addMessages(DEFAULT_MESSAGE_KEY + "=" + dialogRetireConfirmMessage, request, messageSource, null);
			return redirectPrefix + RETIRE_RESUEST + requestSuffix + "?id=" + dialog.getQuestionnaireId().toString();
		}
		dialog.setRetiredBy(userDAO.findById(currentAdmin.getUsername()));
		dialog.setRetiredOn(new Date());
		// dialog.setModifiedBy(userDAO.findById(currentAdmin.getUsername()));
		// dialog.setModifiedOn(new Date());
		dialog.setPublicationStatus(publicationStatusTypeDAO.findById("retired"));
		questionnaireDAO.update(dialog);
		addMessages(DEFAULT_MESSAGE_KEY + "=" + dialogRetireSuccessMessage, request, messageSource, null);
		if (StringUtils.equalsIgnoreCase(submitAction, SUBMIT)) {
			return redirectPrefix + VIEW_REQUEST + requestSuffix + "?id=" + dialog.getQuestionnaireId().toString();
		}

		if (StringUtils.equalsIgnoreCase(submitAction, SUBMIT_AND_EXIT)) {
			return redirectPrefix + LIST_REQUEST + requestSuffix + "?checkSearch=list";
		}
		return redirectPrefix + VIEW_REQUEST + requestSuffix;
	}

	@Transactional()
	@RequestMapping(value = PUBLISH_REQUEST, method = RequestMethod.POST)
	public String publishDialog(@RequestParam
	String submitAction, @ModelAttribute("dialog")
	Questionnaire dialog, Errors errors, ModelMap model, HttpServletRequest request) throws java.text.ParseException {
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		// If the retired note is empty, return to the form, and display a
		// message.
		readMessages(defaultMessageKeys, request);
		readMessages(MessageKeys, request);
		SimpleDateFormat strToDate = new SimpleDateFormat("MM/dd/yyyy");
		String effectiveDateString = "";
		if (request.getParameterValues("effectiveDate") != null) {
			effectiveDateString = request.getParameterValues("effectiveDate")[0];
		}
		Date effectiveDate = strToDate.parse(effectiveDateString);
		dialog.setEffectiveDate(effectiveDate);
		dialog.setPublishedBy(userDAO.findById(currentAdmin.getUsername()));
		dialog.setPublishedOn(new Date());
		// dialog.setModifiedBy(userDAO.findById(currentAdmin.getUsername()));
		// dialog.setModifiedOn(new Date());
		dialog.setPublicationStatus(publicationStatusTypeDAO.findById("published"));
		questionnaireManager.publishQuestionnaire(dialog);
		// questionnaireDAO.update(dialog);
		addMessages(DEFAULT_MESSAGE_KEY + "=" + dialogPublishSuccessMessage, request, messageSource, null);
		if (StringUtils.equalsIgnoreCase(submitAction, SUBMIT)) {
			return redirectPrefix + VIEW_REQUEST + requestSuffix + "?id=" + dialog.getQuestionnaireId().toString();
		}

		if (StringUtils.equalsIgnoreCase(submitAction, SUBMIT_AND_EXIT)) {
			return redirectPrefix + LIST_REQUEST + requestSuffix + "?checkSearch=list";
		}
		return redirectPrefix + VIEW_REQUEST + requestSuffix;
	}

	@Transactional()
	@RequestMapping(value = CHECK_DIALOG_PUBLISH, method = RequestMethod.POST)
	public String checkPublish(@RequestParam
	String id, ModelMap model, HttpServletRequest request, HttpServletResponse response) {
		Questionnaire questionnaire = questionnaireDAO.findById(Long.valueOf(id));
		PrintWriter out = null;
		String message = "";
		String error = "";
		try {
			out = response.getWriter();
		} catch (IOException e) {
			return errorsViewName;
		}
		if (questionnaire.getDecisionServiceName() == null || questionnaire.getDecisionServiceName().equals("")) {
			error += Msg_noServiceName + ";";
			out.print(error);
			return null;
		}

		SimpleDateFormat strToDate = new SimpleDateFormat("MM/dd/yyyy");
		String effectiveDateString = "";
		String publishText = "";
		if (request.getParameterValues("effectiveDate") != null) {
			effectiveDateString = request.getParameterValues("effectiveDate")[0];
		}
		if (request.getParameterValues("publishText") != null) {
			publishText = request.getParameterValues("publishText")[0];
		}

		if (StringUtils.isEmpty(publishText) == true || StringUtils.isEmpty(effectiveDateString) == true) {
			if (StringUtils.isEmpty(publishText)) {
				error += Msg_publishText + ";";
			}

			if (StringUtils.isEmpty(effectiveDateString)) {
				error += Msg_effectiveDate + ";";
			}

		} else {
			if (publishText.length() >= 255) {
				error += Msg_publishTextLen + ";";
			}
		}
		if (error.equals("")) {
			try {
				Date effectiveDate = strToDate.parse(effectiveDateString);
				questionnaire.setEffectiveDate(effectiveDate);
				if (questionnaire.getExpirationDate() == null) {
					questionnaire.setExpirationDate(strToDate.parse("12/31/9999"));
				}
				// questionnaire.setEffectiveDate(effectiveDate)
				List overLappingData = questionnaireManager.checkOverlapping(questionnaire);
				if (overLappingData != null && overLappingData.size() > 0 && overLappingData.get(0) != null) {
					for (int i = 0; i < overLappingData.size(); i++) {
						Questionnaire overnaire = (Questionnaire) overLappingData.get(i);
						error += this.generalPutQuestionnaireHtml(overnaire);
						// error += this.g
					}
				}

			} catch (java.text.ParseException e) {
				// e.printStackTrace();
				error += Msg_incorrectDate + ";";
			}
		}
		out.print(error);
		return null;
	}

	@Transactional()
	@RequestMapping(value = EDIT_REQUEST, method = RequestMethod.POST)
	public String processEditQuestion(@RequestParam
	String submitAction, @ModelAttribute("dialog")
	Questionnaire dialog, Errors errors, ModelMap model, HttpServletRequest request, SessionStatus sessionStatus) {
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		readMessages(defaultMessageKeys, request);
		dialog.setModifiedOn(new Date());
		dialog.setModifiedBy(userDAO.findById(currentAdmin.getUsername()));
		dialog = generalGetSelect(dialog, request);
		questionnaireDAO.update(dialog);
		addMessages(DEFAULT_MESSAGE_KEY + "=" + dialogUpdateSuccessMessage, request, messageSource, null);
		return redirectPrefix + VIEW_REQUEST + requestSuffix + "?id=" + dialog.getQuestionnaireId().toString();
	}

	@Transactional()
	@RequestMapping(value = { CHECK_DIALOG_STATUE, DEL_REQUEST }, method = RequestMethod.POST)
	public String checkDialog(@RequestParam
	String id, ModelMap model, HttpServletRequest request, HttpServletResponse response) {
		Questionnaire questionnaire = questionnaireDAO.findById(Long.valueOf(id));
		String message = "";
		/**
		 * If the Dialog is in Published status, it cannot be updated directly.
		 * The web site will prompt the Author with the message “This action not
		 * available; Dialog is in Published Status”.
		 */
		if (questionnaire.getPublicationStatus() != null && questionnaire.getPublicationStatus().getCode().equals("published")) {
			message = getMessage("", publishedMessage);
		}
		/**
		 * If the Dialog is in Retired status, it cannot be updated directly.
		 * The web site will prompt the Author with the message “This action not
		 * available; Dialog is in Retired Status”.
		 */
		if (questionnaire.getPublicationStatus() != null && questionnaire.getPublicationStatus().getCode().equals("retired")) {
			message = getMessage("", retiredMessage);
		}
		PrintWriter out = null;
		try {
			out = response.getWriter();
		} catch (IOException e) {
			return errorsViewName;
		}
		if (!message.equals("")) {
			out.print("<font color='red'>" + message + "</font>");
		} else {
			if (request.getRequestURI().indexOf(DEL_REQUEST) > -1) {
				questionnaireManager.delQuestionnarie(questionnaire);
				// questionnaireDAO.delete(questionnaire);
				addMessages(DEFAULT_MESSAGE_KEY + "=" + deletedMessage, request, messageSource, null);
				out.print(this.getMessage(questionnaire.getRefId(), deletedMessage) + ":true");// Question
																								// has
																								// been
																								// deleted
			} else {
				out.print(message);
			}
		}
		return null;
	}

	@Transactional()
	@RequestMapping(value = SEARCH_PAGE_REQUEST, method = RequestMethod.POST)
	public String searchPage(ModelMap model, HttpServletRequest request, HttpServletResponse response) {
		List<String> permissions = SecurityUtils.getCurrentUserPermissions();
		// Get the current user.
		CustomUserDetails currentUserDetails = SecurityUtils.getCurrentUser();
		String userName = "";
		String groupName = "";
		User currentUser = userDAO.findById(currentUserDetails.getUsername());
		if (permissions.contains(PermissionType.PORTAL_USER.value())) {
			userName = currentUser.getUsername();
		}
		if (permissions.contains(PermissionType.AUTHOR.value())) {
			groupName = currentUser.getUserGroup().getName();
		}
		String keyWord = request.getParameterValues("keyword")[0];
		List<QuestionSet> questionSets = questionnaireManager.searchPage(keyWord, userName, groupName);
		String outHtml = "";
		for (int i = 0; i < questionSets.size(); i++) {
			QuestionSet set = questionSets.get(i);
			outHtml += this.generalPutHtml(set);
		}
		PrintWriter out = null;
		try {
			out = response.getWriter();
		} catch (IOException e) {
			return errorsViewName;
		}
		out.print(outHtml);

		return null;
	}

	@Transactional()
	@RequestMapping(value = CHECK_PAGE_REQUEST, method = RequestMethod.POST)
	public String checkPage(ModelMap model, HttpServletRequest request, HttpServletResponse response) {
		String pageId = request.getParameterValues("pageId")[0];
		String dialogId = request.getParameterValues("dialogId")[0];
		Questionnaire naire = questionnaireDAO.findById(Long.valueOf(dialogId));
		QuestionSet set = questionSetDAO.findById(Long.valueOf(pageId));
		String pageRefId = set.getRefId();
		String message = "";
		if (questionnaireManager.checkPage(dialogId, pageId)) {
			message = this.getMessage(pageRefId, havePageMessage);
		}
		PrintWriter out = null;
		try {
			out = response.getWriter();
		} catch (IOException e) {
			return errorsViewName;
		}
		out.print(message);
		return null;
	}

	public void generalGet(ModelMap model, boolean findWebservice, User currentUser) {
		List<String> permissions = SecurityUtils.getCurrentUserPermissions();
		List<PublicationStatusType> PublicationStatusTypes = publicationStatusTypeDAO.findAll();
		List<Function> functions = new ArrayList();
		List<Locale> locales = new ArrayList();
		List<Region> regions = new ArrayList();
		List<ProductType> productTypes = new ArrayList();
		List<Theme> themes = new ArrayList();
		if (permissions.contains(PermissionType.SYS_ADMIN.value())) {
			functions = functionDAO.findAll();
			locales = localeDAO.findAll();
			regions = regionDAO.findAll();
			productTypes = productTypeDAO.findAll();
			themes = themeDAO.findAll();
		}
		if (permissions.contains(PermissionType.PORTAL_USER.value())) {
			functions = questionnaireManager.getPortalList("Function");
			locales = questionnaireManager.getPortalList("Locale");
			regions = questionnaireManager.getPortalList("Region");
			productTypes = questionnaireManager.getPortalList("ProductType");
			themes = questionnaireManager.getPortalList("Theme");
		}
		if (permissions.contains(PermissionType.AUTHOR.value()) || permissions.contains(PermissionType.GROUP_ADMIN.value()) || permissions.contains(PermissionType.REVIEWER.value())) {
			functions = questionnaireManager.getGroupList("Function", currentUser.getUserGroup().getName());
			locales = questionnaireManager.getGroupList("Locale", currentUser.getUserGroup().getName());
			regions = questionnaireManager.getGroupList("Region", currentUser.getUserGroup().getName());
			productTypes = questionnaireManager.getGroupList("ProductType", currentUser.getUserGroup().getName());
			themes = questionnaireManager.getGroupList("Theme", currentUser.getUserGroup().getName());
		}

		if (findWebservice) {
			/**
			 * add web service
			 */
			String serviceName = "";
			String[] serviceNames;
			try {
				CcServerMessagingAxisService axis = new CcServerMessagingAxisServiceLocator();
				CcServerMessagingAxis client = axis.getCorticonAdmin();
				serviceName = client.getDecisionServiceNames();

			} catch (RemoteException e) {
				e.printStackTrace();
			} catch (ServiceException e) {
				e.printStackTrace();
			}
			serviceNames = serviceName.split(";");
			serviceName = (serviceName == "" ? "0" : serviceName);
			model.addAttribute("serviceNames", serviceNames);
		}
		// output
		model.addAttribute("status", PublicationStatusTypes);
		model.addAttribute("functions", functions);
		model.addAttribute("locales", locales);
		model.addAttribute("regions", regions);
		model.addAttribute("productTypes", productTypes);
		model.addAttribute("themes", themes);
	}

	public Questionnaire generalGetSelect(Questionnaire dialog, HttpServletRequest request) {
		String function = "";
		String locale = "";
		String region = "";
		String productType = "";
		String theme = "";

		String summaryReport = "";
		String decisionServiceName = "";
		if (request.getParameterValues("function") != null) {
			function = request.getParameterValues("function")[0];
			dialog.setFunction(functionDAO.findById(function));
		} else {
			dialog.setFunction(null);
		}
		if (request.getParameterValues("locale") != null) {
			locale = request.getParameterValues("locale")[0];
			dialog.setLocale(questionnaireManager.getLocale(locale));
		} else {
			dialog.setLocale(null);
		}
		if (request.getParameterValues("region") != null) {
			region = request.getParameterValues("region")[0];
			dialog.setRegion(regionDAO.findById(region));
		} else {
			dialog.setRegion(null);
		}
		if (request.getParameterValues("productType") != null) {
			productType = request.getParameterValues("productType")[0];
			dialog.setProductType(productTypeDAO.findById(productType));
		} else {
			dialog.setProductType(null);
		}
		if (request.getParameterValues("theme") != null) {
			theme = request.getParameterValues("theme")[0];
			dialog.setTheme(themeDAO.findById(theme));
		} else {
			dialog.setTheme(null);
		}

		if (request.getParameterValues("summaryReport") != null) {
			summaryReport = request.getParameterValues("summaryReport")[0];
		}
		if (request.getParameterValues("decisionServiceName") != null) {
			decisionServiceName = request.getParameterValues("decisionServiceName")[0];
		}

		dialog.setDecisionServiceName(decisionServiceName);
		if (summaryReport.equals("true")) {
			dialog.setSummaryReport(true);
		}
		if (summaryReport.equals("false")) {
			dialog.setSummaryReport(false);
		}
		return dialog;
	}

	private Questionnaire escapeQuestionnaire(Questionnaire dialog) {
		dialog.setDescription(HtmlUtils.htmlEscape(dialog.getDescription()));
		dialog.setName(HtmlUtils.htmlEscape(dialog.getName()));
		dialog.setVocabularyname(HtmlUtils.htmlEscape(dialog.getVocabularyname()));
		dialog.setDisplayTitle(HtmlUtils.htmlEscape(dialog.getDisplayTitle()));
		dialog.setPublishText(HtmlUtils.htmlEscape(dialog.getPublishText()));
		dialog.setRetiredNote(HtmlUtils.htmlEscape(dialog.getRetiredNote()));
		return dialog;
	}

	private void loadUsersAndGroupsInfoByPermission(CustomUserDetails currentUser, HttpServletRequest request) {
		List<String> permissions = currentUser.getPermissions();
		List<UserGroup> groups = new ArrayList();
		List<User> users = new ArrayList();
		if (permissions.contains(PermissionType.SYS_ADMIN.value())) {
			users = userDAO.findAll();
			request.setAttribute("users", users);
			groups = userGroupDAO.findAll();
			request.setAttribute("groups", groups);
		} else {
			groups.add(userGroupDAO.findById(currentUser.getGroupName()));
			if (permissions.contains(PermissionType.PORTAL_USER.value())) {
				users.add(userDAO.findById(currentUser.getUsername()));
			} else {
				users = questionManager.getUserByGroupId(currentUser.getGroupName());
			}
			request.setAttribute("users", users);
			request.setAttribute("groups", groups);
		}
	}

	public void generalPutSelect(Questionnaire dialog, ModelMap model) {
		model.addAttribute("function", (dialog.getFunction() == null) ? "" : dialog.getFunction().getCode());
		model.addAttribute("locale", (dialog.getLocale() == null) ? "" : dialog.getLocale().getCode());
		model.addAttribute("region", (dialog.getRegion() == null) ? "" : dialog.getRegion().getCode());
		model.addAttribute("productType", (dialog.getProductType() == null) ? "" : dialog.getProductType().getCode());
		model.addAttribute("theme", (dialog.getTheme() == null) ? "" : dialog.getTheme().getCode());
	}

	public String generalPutHtml(QuestionSet set) {
		String outHtml = "<div id = '" + set.getQuestionSetId() + "' onmouseout=\"qitemMouseOut(this);\" onmouseover=\"qitemHover(this);\" onclick=\"qitemClick(this, " + set.getQuestionSetId() + ",'"
				+ set.getStatus().getCode() + "','" + set.getQuestionSetId() + "')\";>";
		/**
		 * <div onmouseout="qitemMouseOut(this);"
		 * onmouseover="qitemHover(this);" onclick="qitemClick(this, 1502);">
		 * <table cellspacing="0" width="100%" class="data_tbody_title"><tbody>
		 * <tr>
		 * <td width="11%" class="id_number">Q-00016</td>
		 * <td width="10%">1</td>
		 * <td width="13%">active</td>
		 * <td width="66%">sdjfslfjslfjsldjfsljfls</td>
		 * </tr>
		 * <tr>
		 * <td class="tro" colspan="4"/></tr>
		 * </tbody></table></div>
		 */
		outHtml += "<table cellspacing=\"0\" width=\"100%\" class=\"data_tbody_title\"><tbody>";
		outHtml += "<tr><td width=\"10%\" id=\"name\" class=\"id_number\">" + set.getName() + "<td width=\"10%\" id=\"refId\" class=\"id_number\">" + set.getRefId()
				+ "</td><td width=\"7%\" id=\"version\">" + set.getVersion() + "</td><td id=\"qtext\" width=\"20%\">" + set.getListdisplayTitle() + "</td><td width=\"15%\">"
				+ set.getStatus().getCode() + "</td><td width=\"15%\" id = \"availability\">" + set.getAvailability().getCode() + "</td></tr>";
		outHtml += "<tr><td class=\"tro\" colspan=\"4\"/></tr></tbody></table></div>";
		return outHtml;
	}

	public String generalPutQuestionnaireHtml(Questionnaire questionnaire) {
		String outHtml = "<div id=OverlappingData onmouseout=\"qitemMouseOut(this);\" onmouseover=\"qitemHover(this);\" onclick=\"qitemClick(this, " + questionnaire.getQuestionnaireId() + ")\";>";
		/**
		 * <table width="100%" cellspacing="0" class="data_tbody_title"> <tbody>
		 * <tr>
		 * <td width="8%" class="id_number">D00006</td>
		 * <td width="7%">Version</td>
		 * <td width="17%">Online An for Li…</td>
		 * <td width="9%">apply_life</td>
		 * <td width="8%">Function</td>
		 * <td width="7%">Region</td>
		 * <td width="10%">Life-Term</td>
		 * <td width="10%">US-English</td>
		 * <td width="12%">01-Dec-2008</td>
		 * <td width="12%">31-Dec-9999</td>
		 * </tr>
		 * <tr>
		 * <td colspan="10" class="tro"></td>
		 * </tr>
		 * </tbody> </table>
		 */
		outHtml += "<table cellspacing=\"0\" width=\"100%\" class=\"data_tbody_title\"><tbody>";
		outHtml += "<tr><td width=\"10%\" class=\"id_number\">" + questionnaire.getName() + "<tr><td width=\"8%\" class=\"id_number\">" + questionnaire.getRefId() + "</td><td width=\"7%\">"
				+ questionnaire.getVersion() + "</td><td width=\"15%\">" + questionnaire.getName() + "</td><td width=\"9%\">" + questionnaire.getDisplayTitle() + "</td><td width=\"8%\">"
				+ questionnaire.getFunction().getCode() + "</td><td width=\"7%\">" + questionnaire.getRegion().getCode() + "</td><td width=\"10%\">" + questionnaire.getProductType().getCode()
				+ "</td><td width=\"10%\">" + questionnaire.getLocale().getCode() + "</td><td width=\"10%\">" + questionnaire.getEffectiveDate() + "</td><td width=\"12%\">"
				+ questionnaire.getExpirationDate() + "</td></tr>";
		outHtml += "<tr><td class=\"tro\" colspan=\"4\"/></tr></tbody></table></div>";
		return outHtml;
	}

	public String generalPageHtml(QuestionSetInNaire naire, int i) {
		// String text = naire.getQuestionSet().getText();
		// text = (text == null ? "" : text);
		// if (text.length() >= 35) {
		// text = text.substring(0, 35);
		// }
		String outHtml = "<table width=\"100%\" sequence=\"" + naire.getSequence() + "\" qsId=\"" + naire.getQuestionSet().getQuestionSetId() + "\" title=\""
				+ naire.getQuestionSet().getListdisplayTitle() + "\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" onclick=\"itemClick(this, 'id="
				+ naire.getQuestionSet().getQuestionSetId().toString() + "','" + naire.getId().toString() + "');\" id=\"questionSet" + naire.getQuestionSet().getQuestionSetId() + "\">";
		/**
		 * <table width="100%" border="0" cellpadding="0" cellspacing="0"
		 * id="questionSet${qis.questionSet.questionSetId}"
		 * title="${qis.questionSet.displayTitle}"
		 * qsId="${qis.questionSet.questionSetId}" sequence="${qis.sequence}"
		 * onclick="itemClick(this,
		 * 'id=${qis.questionSet.questionSetId}','${qis.id}');"> <tbody>
		 * <tr>
		 * <th width="5%" class="number0">2</th>
		 * <td width="18%" class="row1">P00002</td>
		 * <td width="8%" class="row2">Ver 2</td>
		 * <td width="16%" class="row3">open/active</td>
		 * <td width="46%" class="row4"> jfakfj&8%$#@*fsdlkfjsdlfjslkfjweofj鈥?</td>
		 * </tr>
		 * </tbody></table>
		 */
		outHtml += "<tbody><tr><th width=\"5%\" class=\"number0\">" + (i + 1) + "</th><td width=\"15%\" class=\"row1\">" + naire.getQuestionSet().getName() + "</th><td width=\"18%\" class=\"row2\">"
				+ naire.getQuestionSet().getRefId() + "</td><td width=\"8%\" class=\"row2\">Ver" + naire.getQuestionSet().getVersion() + "</td>";
		outHtml += "<td width=\"16%\" class=\"row3\">" + naire.getQuestionSet().getAvailability().getName() + "/" + naire.getQuestionSet().getStatus().getName()
				+ "</td><td width=\"31%\" class=\"row4\"> " + naire.getQuestionSet().getListdisplayTitle() + "</td></tr> </tbody></table>";

		return outHtml;
	}

	@RequestMapping(value = REPLICATE_REQUEST, method = RequestMethod.GET)
	public String getReplicate(@RequestParam
	Long id, ModelMap model, HttpServletRequest request) throws IllegalAccessException, InvocationTargetException {

		request.setAttribute(OPERATION_KEY, REPLICATE_REQUEST);

		Questionnaire base = questionnaireDAO.findById(id);
		Assert.notNull(base);

		if (permissionCheck(base)) {
			redirectTo403();
		}

		Questionnaire newOne = Questionnaire.newInstance();
		// Copy properties
		BeanUtils.copyProperties(newOne, base);

		// Set properties.
		newOne.setVersion(1);
		newOne.setSibling(base);
		newOne.setPublicationStatus(publicationStatusTypeDAO.load("inprocess"));

		// Set the modified infos null.
		newOne.setModifiedBy(null);
		newOne.setModifiedOn(null);
		
		// update by last commit 2009.7.1
		// Set refId.
//		String maxRefId = questionnaireDAO.findMaxRefId();
//		String nextRefId;
//		if (maxRefId == null) {
//			nextRefId = QuestionUtils.DIALOG_REFID_PREFIX + QuestionUtils.REFID_BEGIN;
//		} else {
//			nextRefId = QuestionUtils.getNextRefId(maxRefId);
//		}
//		newOne.setRefId(nextRefId);
		newOne.setRefId(null);
		model.addAttribute("questionnaire", newOne);

		// loadDataToSession(model);
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		User currentUser = userDAO.findById(currentAdmin.getUsername());
		generalGet(model, true, currentUser);

		// Set a message.
		request.setAttribute(DEFAULT_MESSAGE_KEY, getMessage("common.action.prompt"));

		// Read messages.
		readMessages(defaultMessageKeys, request);

		showMessages(request);

		return getViewNameByRequestURI(request);
	}

	@RequestMapping(value = REPLICATE_REQUEST, method = RequestMethod.POST)
	public String postReplicate(@RequestParam
	String submitAction, HttpServletRequest request, @ModelAttribute
	Questionnaire questionnaire, Errors errors, SessionStatus sessionStatus) throws IllegalAccessException, InvocationTargetException, JSONException {

		request.setAttribute(OPERATION_KEY, REPLICATE_REQUEST);
		showMessages(request);

		// Validate the form object.
		Map<String, List<String>> errorsMessages = questionnaireValidator.invokeValidate(questionnaire, errors, request.getLocale());
		request.setAttribute("errors", errorsMessages);

		if (errors.hasErrors()) {
			return getViewNameByRequestURI(request);
		}

		List<QuestionSetDTO> qsDTOList = getQuestionSetsInfo(request, "questionSetsData");
		// update by last commit 2009.7.1
		String maxRefId = questionnaireDAO.findMaxRefId();
		String nextRefId;
		if (maxRefId == null) {
			nextRefId = QuestionUtils.DIALOG_REFID_PREFIX + QuestionUtils.REFID_BEGIN;
		} else {
			nextRefId = QuestionUtils.getNextRefId(maxRefId);
		}
		questionnaire.setRefId(nextRefId);
		questionnaireService.replicate(questionnaire, qsDTOList);

		sessionStatus.setComplete();

		String successMessage = getMessage("questionnaire.replicate.success");
		request.getSession().setAttribute(DEFAULT_MESSAGE_KEY, successMessage);

		return redirectBySubmitAction(submitAction, "id=" + questionnaire.getQuestionnaireId());
	}

	@RequestMapping(value = NEW_VERSION_REQUEST, method = RequestMethod.GET)
	public String getNewVersion(@RequestParam
	Long id, HttpServletRequest request, ModelMap model) {
		request.setAttribute(OPERATION_KEY, NEW_VERSION_REQUEST);

		Questionnaire questionnaire = questionnaireDAO.findById(id);
		Assert.notNull(questionnaire);

		if (permissionCheck(questionnaire)) {
			redirectTo403();
		}

		// If a questionnaire is retired, it cannot be new versioned.
		if (questionnaire.getPublicationStatus().getCode().equals(PublicationStatus.RETIRED.getCode())) {
			String retiredStatusMessage = getMessage("dialog.retired");
			request.getSession().setAttribute(DEFAULT_MESSAGE_KEY, retiredStatusMessage);
			return redirectPrefix + LIST_REQUEST + requestSuffix;
		}

		// Set new version.
		long nextVersion = questionnaireDAO.findMaxVersionByRefId(questionnaire.getRefId()) + 1;
		questionnaire.setVersion(nextVersion);
		questionnaire.setPublicationStatus(publicationStatusTypeDAO.load(PublicationStatus.IN_PROCESS.getCode()));

		model.addAttribute(questionnaire);

		// loadDataToSession(model);
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		User currentUser = userDAO.findById(currentAdmin.getUsername());
		generalGet(model, true, currentUser);

		String message = getMessage("common.action.prompt");
		request.setAttribute(DEFAULT_MESSAGE_KEY, message);

		showMessages(request);

		return getViewNameByRequestURI(request);
	}

	@RequestMapping(value = NEW_VERSION_REQUEST, method = RequestMethod.POST)
	public String postNewVersion(@RequestParam
	String submitAction, HttpServletRequest request, @ModelAttribute
	Questionnaire questionnaire, Errors errors, SessionStatus sessionStatus) throws JSONException {

		request.setAttribute(OPERATION_KEY, NEW_VERSION_REQUEST);
		showMessages(request);

		// Validate the form object.
		Map<String, List<String>> errorsMessages = questionnaireValidator.invokeValidate(questionnaire, errors, request.getLocale());
		request.setAttribute("errors", errorsMessages);

		if (errors.hasErrors()) {
			return getViewNameByRequestURI(request);
		}

		/*
		 * The logic of the newversion and the copy operations are same except
		 * the value of the refId and version.
		 */
		List<QuestionSetDTO> qsDTOList = getQuestionSetsInfo(request, "questionSetsData");
		questionnaireService.copy(questionnaire, qsDTOList);

		sessionStatus.setComplete();

		String successMessage = getMessage("questionnaire.newversion.success");
		request.getSession().setAttribute(DEFAULT_MESSAGE_KEY, successMessage);

		return redirectBySubmitAction(submitAction, "id=" + questionnaire.getQuestionnaireId());
	}

	/**
	 * @param id
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value = COPY_REQUEST, method = RequestMethod.GET)
	public String getCopy(@RequestParam
	Long id, HttpServletRequest request, ModelMap model) {

		request.setAttribute(OPERATION_KEY, COPY_REQUEST);

		Questionnaire base = questionnaireDAO.findById(id);
		Assert.notNull(base);

		if (!permissionCheck(base)) {
			return redirectTo403();
		}
		// update by last commit 2009.7.1
//		String maxRefId = questionnaireDAO.findMaxRefId();
//		String nextRefId = QuestionUtils.getNextRefId(maxRefId);
//		base.setRefId(nextRefId);

		// Set others properties.
		base.setRefId(null);
		base.setVersion(1);
		base.setModifiedBy(null);
		base.setModifiedOn(null);
		base.setRetiredBy(null);
		base.setRetiredNote(null);
		base.setRetiredOn(null);
		base.setPublicationStatus(publicationStatusTypeDAO.load(PublicationStatus.IN_PROCESS.getCode()));
		base.setPublishText(null);
		base.setPublishedBy(null);
		base.setPublishedOn(null);

		model.addAttribute(base);
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		User currentUser = userDAO.findById(currentAdmin.getUsername());
		generalGet(model, true, currentUser);
		// loadDataToSession(model);

		String message = getMessage("common.action.prompt");
		request.setAttribute(DEFAULT_MESSAGE_KEY, message);

		showMessages(request);

		return getViewNameByRequestURI(request);
	}

	@RequestMapping(value = COPY_REQUEST, method = RequestMethod.POST)
	public String postCopy(@RequestParam
	String submitAction, HttpServletRequest request, @ModelAttribute
	Questionnaire questionnaire, Errors errors, SessionStatus sessionStatus) throws JSONException {

		request.setAttribute(OPERATION_KEY, COPY_REQUEST);
		showMessages(request);

		// Validate the form object.
		Map<String, List<String>> errorsMessages = questionnaireValidator.invokeValidate(questionnaire, errors, request.getLocale());
		request.setAttribute("errors", errorsMessages);

		if (errors.hasErrors()) {
			return getViewNameByRequestURI(request);
		}
		// update by last commit 2009.7.1
		String maxRefId = questionnaireDAO.findMaxRefId();
		String nextRefId = QuestionUtils.getNextRefId(maxRefId);
		questionnaire.setRefId(nextRefId);
		
		List<QuestionSetDTO> qsDTOList = getQuestionSetsInfo(request, "questionSetsData");
		questionnaireService.copy(questionnaire, qsDTOList);

		sessionStatus.setComplete();

		// Add the copy operation success message.
		String successMessage = getMessage("questionnaire.copy.success");
		request.getSession().setAttribute(DEFAULT_MESSAGE_KEY, successMessage);

		return redirectBySubmitAction(submitAction, "id=" + questionnaire.getQuestionnaireId());
	}

	@RequestMapping(value = DialogsRequestURL.PREVIEW_ON_EDIT, method = RequestMethod.GET)
	public String previewOnEdit(@RequestParam
	Long qsId, HttpServletRequest request) {

		// Get the question set instance according to the question set id.
		QuestionSet currentQuestionSet = questionSetDAO.findById(qsId);

		// The current question set cannot be null.
		Assert.notNull(currentQuestionSet);

		// Get the PreviewQuestionDTO list according to the question set
		// instance.
		List<PreviewQuestionDTO> dtoList = questionSetService.getPreviewQuestionDTOList(currentQuestionSet);

		// Set the PreviewQuestionDTO list into the request context.
		request.setAttribute("questions", dtoList);
		request.setAttribute("title", currentQuestionSet.getDisplayTitle());

		return getViewNameByRequestURI(request);
	}

	@RequestMapping(value = DialogsRequestURL.PREVIEW, method = RequestMethod.GET)
	public String preview(@RequestParam
	Long qnId, HttpServletRequest request) {

		Questionnaire qn = questionnaireDAO.load(qnId);

		/*
		 * Add the questionnaire instance into the request context, used to
		 * render the question set list.
		 */
		request.setAttribute("qn", qn);

		List<List> questionSetList = new ArrayList<List>();

		for (QuestionSetInNaire qsin : qn.getQuestionSetsInNaire()) {
			// Get the PreviewQuestionDTO list according to the question set
			// instance.
			List<PreviewQuestionDTO> dtoList = questionSetService.getPreviewQuestionDTOList(qsin.getQuestionSet());
			questionSetList.add(dtoList);
		}

		request.setAttribute("questionSets", questionSetList);

		return getViewNameByRequestURI(request);
	}

	@RequestMapping(value = DialogsRequestURL.SEARCH, method = RequestMethod.GET)
	public String search(@RequestParam(required = false)
	Integer page, HttpServletRequest request, ModelMap model) {

		/**
		 * Get the search criterions.
		 */
		String keywords = request.getParameter("keywords");

		String function = request.getParameter("function");
		function = function == null ? "" : function;

		String region = request.getParameter("region");
		region = region == null ? "" : region;

		String productType = request.getParameter("productType");
		productType = productType == null ? "" : productType;

		String locale = request.getParameter("locale");
		locale = locale == null ? "" : locale;

		String status = request.getParameter("status");
		status = status == null ? "" : status;

		String username = request.getParameter("user");
		username = username == null ? "" : username;

		String groupName = request.getParameter("group");
		groupName = groupName == null ? "" : groupName;

		// Construct Pager
		Pager pager = constructPager(page, request);

		// Add sort info.
		setPagerSort(pager, "questionnaireId", request);

		String requestParameters = "&keywords=" + keywords + "&function=" + function + "&region=" + region + "&productType=" + productType + "&locale=" + locale + "&status=" + status;

		// Construct the search criterions according to the role of the current
		// user. And set the
		// username and groupname params into the request scope.
		CustomUserDetails currentUser = SecurityUtils.getCurrentUser();
		List<String> permissions = currentUser.getPermissions();
		if (permissions.contains(PermissionType.GROUP_ADMIN.value()) || permissions.contains(PermissionType.AUTHOR.value()) || permissions.contains(PermissionType.REVIEWER.value())) {
			groupName = currentUser.getGroupName();
			requestParameters = requestParameters + "&group=" + groupName;
		} else if (permissions.contains(PermissionType.PORTAL_USER.value())) {
			username = currentUser.getUsername();
			requestParameters = requestParameters + "&user=" + username;
		} else {
			requestParameters = requestParameters + "&user=" + username + "&group=" + groupName;
		}

		// Set the search criterions into the pager object.
		pager.setRequestParameters(pager.getRequestParameters() + requestParameters);
		request.getSession().setAttribute(SEARCH_KEYWORD, pager.getRequestParameters() + requestParameters);
		List<Questionnaire> results = new ArrayList<Questionnaire>();

		if (StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(groupName)) {
			User searchedUser = userDAO.findById(username);
			if (searchedUser != null && searchedUser.getUserGroup().getName().equals(groupName)) {
				results = questionnaireDAO.search(keywords, function, region, productType, locale, status, username, groupName, pager);
			}
		} else {
			results = questionnaireDAO.search(keywords, function, region, productType, locale, status, username, groupName, pager);
		}

		// loadDataToRequest(request);
		CustomUserDetails currentAdmin = SecurityUtils.getCurrentUser();
		User user = userDAO.findById(currentAdmin.getUsername());
		generalGet(model, false, user);
		commonSupport.loadUsersAndGroupsInfoByPermission(currentUser, request);

		if (results.size() > 0) {
			request.setAttribute("dialogs", results);
			request.setAttribute("error", getMessage(String.valueOf(pager.getNumOfRecords()), questionnaireFoundMessage));
		} else {
			request.setAttribute("error", getMessage("", publicNotFoundMessage));
		}

		request.setAttribute("pager", pager);

		return getViewNameByRequestURI(request);
	}

	// ********** Inner Methods Begin ********** //
	/**
	 * This method loads Functions, Regions, Product Lines, Locales and Themes
	 * into the session scope for the create, edit, copy, new version and
	 * replicate functions.
	 * 
	 * @param model
	 */
	private void loadDataToSession1(ModelMap model) {
		List<Function> functions = functionDAO.findAll();
		List<Locale> locales = localeDAO.findAll();
		List<Region> regions = regionDAO.findAll();
		List<ProductType> productTypes = productTypeDAO.findAll();
		List<Theme> themes = themeDAO.findAll();
		model.addAttribute("functions", functions);
		model.addAttribute("locales", locales);
		model.addAttribute("regions", regions);
		model.addAttribute("productTypes", productTypes);
		model.addAttribute("themes", themes);

		String serviceName = null;
		List<String> serviceNames = new ArrayList<String>();
		try {
			CcServerMessagingAxisService axis = new CcServerMessagingAxisServiceLocator();
			CcServerMessagingAxis client = axis.getCorticonAdmin();
			serviceName = client.getDecisionServiceNames();

		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (ServiceException e) {
			e.printStackTrace();
		}

		if (serviceName != null) {
			serviceNames = Arrays.asList(serviceName.split(";"));
		}

		model.addAttribute("serviceNames", serviceNames);
	}

	private void loadDataToRequest1(HttpServletRequest request) {
		List<Function> functions = functionDAO.findAll();
		request.setAttribute("functions", functions);

		List<Locale> locales = localeDAO.findAll();
		request.setAttribute("locales", locales);

		List<Region> regions = regionDAO.findAll();
		request.setAttribute("regions", regions);

		List<ProductType> productTypes = productTypeDAO.findAll();
		request.setAttribute("productTypes", productTypes);

		List<Theme> themes = themeDAO.findAll();
		request.setAttribute("themes", themes);
	}

	private boolean permissionCheck(Questionnaire questionnaire) {
		CustomUserDetails currentUser = SecurityUtils.getCurrentUser();
		if (currentUser.getPermissions().contains(PermissionType.PORTAL_USER.value()) && !questionnaire.getModifiedBy().getUsername().equals(currentUser.getUsername())) {
			return false;
		} else if (currentUser.getPermissions().contains(PermissionType.AUTHOR.value()) && !questionnaire.getModifiedBy().getUserGroup().getName().equals(currentUser.getGroupName())) {
			return false;
		}
		return true;
	}

	private List<QuestionSetDTO> getQuestionSetsInfo(HttpServletRequest request, String paramId) throws JSONException {
		// The data of questionSets is in the format of JSON.
		String questionsData = request.getParameter(paramId);

		// Construct a JSONObject according to the questionsData.
		JSONArray questions = new JSONArray(questionsData);

		List<QuestionSetDTO> dtos = new ArrayList<QuestionSetDTO>();

		for (int i = 0; i < questions.length(); i++) {
			JSONObject questionSetJSON = questions.getJSONObject(i);
			QuestionSetDTO dto = new QuestionSetDTO();
			dto.setId(Long.parseLong(questionSetJSON.getString("id")));
			dto.setSequence(questionSetJSON.getString("sequence"));

			dtos.add(dto);
		}

		return dtos;
	}

	private void showMessages(HttpServletRequest request) {
		String Msg_HaveIt = getMessage("", dialogIncludeHaveMessage);
		String Msg_IncludeIt = getMessage("", dialogIncludeSuccessMessage);
		String Msg_Retire = getMessage("", dialogIncludeRetireMessage);
		String Msg_SelectOne = getMessage("", dialogIncludeSelectMesssage);
		request.setAttribute("Msg_HaveIt", Msg_HaveIt);
		request.setAttribute("Msg_IncludeIt", Msg_IncludeIt);
		request.setAttribute("Msg_Retire", Msg_Retire);
		request.setAttribute("Msg_SelectOne", Msg_SelectOne);
	}

	// ********** Inner Methods End ********** //
	@RequestMapping(value = EXPORT_XMI_REQUEST, method = RequestMethod.GET)
	public String list(@RequestParam
	String id, HttpServletRequest request, HttpServletResponse response) {
		cfg.setClassForTemplateLoading(this.getClass(), "/");
		cfg.setObjectWrapper(new DefaultObjectWrapper());
		cfg.setNumberFormat("################");
		Questionnaire dialog = questionnaireDAO.findById(Long.valueOf(id));
		List questions = questionnaireManager.getAllQuestions(dialog);
		List uiControl = uiControlDAO.findAll();
		List resType = questionnaireManager.getResponseType();
		List dataType = dataTypeDAO.findAll();
		for (int i=0;i<dataType.size();i++){
			DataType d = (DataType) dataType.get(i);
			if (d.getName().equals("Float")){
				dataType.remove(d);
				DataType d1 = new DataType();
				d1.setName("Double");
				d1.setCode("Double");
				dataType.add(d1);
			}
		}
		/**
		 * Add Parameter: Only check responseType = display Question
		 */

		String realPath = request.getRealPath("");
		String templatePath = realPath + "/exportxmi_temp/";
		String path = templatePath;

		String fileName = "";
		File newsDir = new File(path);
		if (newsDir.exists()) {
			fileName = path + "/" + dialog.getVocabularyname() + ".xml";
		} else {
			newsDir.mkdirs();
			fileName = path + "/" + dialog.getVocabularyname() + ".xml";
		}
		Map root = new HashMap();
		root.put("model", dialog);
		root.put("questions", questions);
		root.put("uiControl", uiControl);
		root.put("resType", resType);
		root.put("dataType", dataType);
		Template template;
		try {
			template = cfg.getTemplate("exportXMI.ftl");
			Writer out = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8");

			template.process(root, out);

			out.flush();
			out.close();
			response.setContentType("text/xml");
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Content-Disposition", "attachment; filename=" + dialog.getVocabularyname() + ".xml");
			ServletOutputStream out1 = response.getOutputStream();
			//InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName));
	        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
            String line = br.readLine();
            while (line != null) {
                out1.write(line.getBytes()); 
                out1.write("\r\n".getBytes());
                line = br.readLine();
            }
            out1.close();
            br.close();
			
			
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}
}
